home *** CD-ROM | disk | FTP | other *** search
- /* ELM: (c) Jos & Kees Lemmens; Oktober 1993.
-
- This program behaves in a simular way as the UNIX 'elm' program,
- which is very popular among UNIX users. (although it has much less
- functionality !)
- However, the code was written completely by ourselves and we didn't
- need much more !!
- Unfortunately it can only handle local mail, but it is easy to add
- an external program that can handle uucp mail.
-
- Code runs on ATARI (under MINT), on AMIGA 500-4000 (with gcc) and
- was also tested on several UNIX platforms.
-
- 1.4 : cursor keys on Atari console now recognized;
- uucp mailaddresses redirected to OutboudMail function (same
- function as for Internet mail)
-
- Any questions or suggestions about this program can be send to:
- lemmens@dv.twi.tudelft.nl
- */
-
- /* standard headers */
-
- #include <stdio.h>
- #include <stdlib.h> /* getenv, malloc, free and exit */
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <stdarg.h>
-
- #ifdef __MINT__
- #include <osbind.h>
- #include <termcap.h>
- #include <ioctl.h> /* ioctl & tty structs */
- #include <fcntl.h> /* O_RDONLY (access) */
- #else
- #include <curses.h>
- #include <term.h>
- #include <termios.h>
- #include <sys/wait.h>
- #endif
-
- /* UNIX headers */
-
- #include <signal.h> /* only for suspend routine */
- #include <unistd.h>
-
- /* special headers */
-
- #include "elm.h"
-
- static char *version = "[ELM ST, J&KL; v1.4]";
-
- /* termcap variables */
-
- static char *_tcpent,*_tcpbuf;
- static char *CL,*CM,*SO,*SE,*CE,*ME,*MR;
- static int LINES,COLS;
-
- #ifdef __MINT__
- struct ltchars ltold,ltnew; /* disable suspend */
-
- void ttraw(struct ltchars *ltold,struct ltchars *ltnew)
- {
- if(ioctl(0, TIOCGLTC, (char *) ltold) < 0)
- puts("Can't do ioctl");
- ioctl(0, TIOCGLTC, (char *)ltnew);
-
- ltnew->t_suspc = ltnew->t_dsuspc = 0xFF;
- ioctl(0, TIOCSLTC, (char *) ltnew);
- }
-
- void ttcooked(struct ltchars *ltold)
- {
- ioctl(0, TIOCSLTC, (char *) ltold);
- }
- #endif
-
- void InitTermcap(void)
- { char *tmp;
-
- if((tmp=getenv("TERM")) != NULL) /* use UNIX termcap */
- { _tcpent = (char *)malloc(2048); /* must be enough ! */
- tgetent(_tcpent,tmp);
- _tcpbuf = _tcpent +1024;
-
- CL = tgetstr("cl", &_tcpbuf); CM = tgetstr("cm", &_tcpbuf);
- SO = tgetstr("so", &_tcpbuf); SE = tgetstr("se", &_tcpbuf);
- CE = tgetstr("ce", &_tcpbuf); ME = tgetstr("me", &_tcpbuf);
- MR = tgetstr("mr", &_tcpbuf);
-
- if((tmp=getenv("LINES")) == NULL)
- LINES = tgetnum("li");
- else
- LINES = atoi(tmp);
-
- if((tmp=getenv("COLUMNS")) == NULL)
- COLS = tgetnum("co");
- else
- COLS = atoi(tmp);
- }
- else /* set acceptable defaults : VT52 code */
- { CL = "\33H\33J"; CM = "\33Y%+ %+ ";
- SO = "\33p"; SE = "\33q";
- CE = "\33K";
- LINES = 24; COLS = 80;
- }
- }
-
- #ifdef __hpux /* stupid error in HPUX 9.01 headerfile */
- int outc(char c)
- #else
- int outc(int c)
- #endif
- { return putchar(c);
- }
-
- void Clrscr(void)
- { tputs(CL,1,outc);
- }
-
- void Clrtoeol(void)
- { tputs(CE,1,outc);
- }
-
- void Gotoxy(int x,int y)
- { tputs(tgoto(CM, x, y),1,outc);
- }
-
- void EndTermcap(void)
- { free(_tcpent);
- }
-
- void PutStr (char *string,...)
- { va_list ptr;
-
- if(string == NULL)
- return;
-
- va_start(ptr,string);
- vfprintf(stdout,string,ptr);
- fflush(stdout);
- va_end(ptr);
- }
-
- char GetChar(void)
- { char c;
-
- #ifdef __MINT__
- /* this fixes for ATARI cursor keys using scancodes */
- static union { long scan; char byte[4]; } ch;
-
- ch.scan=Crawcin();
- if (ch.byte[3] == 0)
- switch(ch.byte[1])
- { case 'H': return 'k'; /* cursor up */
- case 'P': return 'j'; /* cursor down */
- /* case 'K': return 'h'; /* cursor left */
- /* case 'M': return 'l'; /* cursor right */
- }
-
- c = ch.byte[3];
- #else
- #ifdef __AMIGA__ /* doesn't echo for some reason */
- read(fileno(stdin),&c,1);
- write(fileno(stdout),&c,1);
- #else
- read(fileno(stdin),&c,1);
- #endif
- #endif
- return c;
- }
-
- char *GetStr(char *string,int size)
- {
- #ifdef __AMIGA__
- /* this implies that input editing (backspacing) is not possible ! */
- int count=0;
- do
- { *string = GetChar();
- if(*string == '\r')
- { *string = '\0';
- break;
- }
- } while(string++,count++ < size);
- #else
- fgets(string,size,stdin);
- #endif
-
- /* todo: try fflush(stdin) on AMIGA, maybe this works !! */
-
- return string;
- }
-
- void usage(void)
- { fputs("\nUsage: elm [-f <mailfile>] [-e <editor>]\n",stderr);
- exit(1);
- }
-
- void PutStatus(char *string,...)
- { va_list ptr;
-
- va_start(ptr,string);
- Gotoxy(0,LINES-2);
- Clrtoeol();
- vfprintf(stdout,string,ptr);
- fflush(stdout);
- va_end(ptr);
- }
-
- void PutHeader(Mbox *M)
- { Gotoxy(5,STARTHEADER);
- PutStr("Mailbox '%.30s' with %d messages %s",M->Path,M->Count,version);
- }
-
- void PutMenus(void)
- {
- Gotoxy(4,STARTMENU);
- PutStr("m)ail user; f)orward user; r)eply user; $ = reread mailfile; q)uit");
- Gotoxy(3,STARTMENU+1);
- PutStr("k = move up; j = move down; s)ave to file; d)elete mail; u)ndelete mail");
- Gotoxy(4,STARTMENU+2);
- PutStr("! = start shell; To read a message, press RETURN");
- }
-
- void PutMessage(Mbox *M,int x)
- { int offset = 0;
-
- offset = M->CurMsg /(MSGLISTSIZE) * MSGLISTSIZE;
-
- Gotoxy(0,x-offset+STARTLIST);
-
- PutStr (" %1.1s %.3d %-6.6s %-15.15s (%.3d) %-35.35s",
- &M->Msglist[x]->flag, x+1,
- M->Msglist[x]->date + 4,
- M->Msglist[x]->sender,
- M->Msglist[x]->nrlines,
- M->Msglist[x]->subject);
- }
-
- void PutMessages(Mbox *M)
- { int x;
- int offset = 0;
-
- offset = M->CurMsg /(MSGLISTSIZE) * MSGLISTSIZE;
-
- for(x=0;x<MSGLISTSIZE && x+offset<M->Count; x++)
- PutMessage(M,offset+x);
-
- while(x<MSGLISTSIZE)
- { Gotoxy(0,x+STARTLIST);
- Clrtoeol();
- x++;
- }
- }
-
- void OpenMailbox(Mbox *M)
- { if((M->fd = fopen (ux2dos(M->Path), "r")) == NULL)
- { /* create an empty mailfile */
- if((M->fd = fopen (ux2dos(M->Path), "w+")) == NULL)
- { fprintf(stderr,"Can't open mailbox for %s\n",M->User);
- exit(1);
- }
- else
- { PutStatus("Empty mailbox %s created; Press a key ...",
- M->Path);
- GetChar();
- }
- }
- }
-
- void CloseMailbox(Mbox *M)
- { fclose(M->fd);
- }
-
- void RemoveCR(char *ptr)
- { char *tmp;
-
- if((tmp=strchr(ptr,'\n')) != NULL) *tmp = 0;
- }
-
- char *EatWhiteSpace(char *ptr)
- { while(*ptr == ' ' || *ptr == '\t') ptr++;
- return ptr;
- }
-
- void BuildMailList(Mbox *M)
- { int x;
- int nrlines=0;
- char regel[MAXSTR+1], *tmp1,*tmp2;
-
- OpenMailbox(M);
-
- for(x=0;x < MAXMSG && !feof(M->fd);x++ )
- {
- /* first search for start of (next) message */
- while (strncmp (regel, "From ", 5) && !feof(M->fd) )
- { fgets(regel,MAXSTR,M->fd);
- nrlines++;
- }
-
- if(feof(M->fd)) break;
-
- M->Msglist[x] = calloc(1,sizeof(Msg));
- M->Msglist[x]->start = ftell(M->fd) - strlen(regel) - 1;
- M->Msglist[x]->flag = 'N';
- M->Msglist[x]->status = 0;
- /* assume new msg until proved to be old */
-
- if(x>0) M->Msglist[x-1]->nrlines = nrlines;
-
- nrlines=0; /* start new line count */
-
- if((tmp1 = strchr (regel, ' ')) != NULL) /* sender */
- { tmp1 = EatWhiteSpace(tmp1);
-
- if((tmp2 = strchr (tmp1, ' ')) != NULL) /* date */
- { *tmp2++ = 0; /* fix end of tmp1 */
- tmp2 = EatWhiteSpace(tmp2);
- strncpy(M->Msglist[x]->date,tmp2,MAXDATE);
- }
- strncpy(M->Msglist[x]->sender,tmp1,MAXNAME);
- }
- do
- { fgets (regel,MAXSTR,M->fd);
- nrlines++;
-
- if(!strncmp (regel, "Status:",7))
- { if(strchr(regel + 7,'R') != NULL)
- M->Msglist[x]->flag = ' ';
- M->Msglist[x]->status = 1;
- }
- else if(!strncmp (regel, "Subject:",8))
- { tmp1 = EatWhiteSpace(regel + 8);
- RemoveCR(tmp1);
- strncpy(M->Msglist[x]->subject,tmp1,MAXSUBJECT);
- }
- }while (strncmp (regel, "From ", 5) && !feof(M->fd) );
- }
-
- if(x>0) M->Msglist[x-1]->nrlines = nrlines; /* save length for last message */
-
- /* last (extra) record is only used save end of file position */
-
- M->Msglist[x] = calloc(1,sizeof(Msg));
- M->Msglist[x]->start = ftell(M->fd);
-
- if(x == 0) /* fix for empty file */
- { M->Msglist[1] = calloc(1,sizeof(Msg));
- M->Msglist[1]->start = ftell(M->fd);
- }
-
- M->Count = x;
- M->CurMsg = 0;
- CloseMailbox(M);
- }
-
- void SetCurMsg(Mbox *M,int new,int echo)
- { int old;
-
- old = M->CurMsg;
-
- if(new < 0 || new >=M->Count)
- { if(echo) PutStatus("No more messages");
- Gotoxy(0,STARTLIST + old%MSGLISTSIZE); PutStr("-> ");
- return;
- }
- M->CurMsg = new;
-
- if(old /(MSGLISTSIZE) != new /(MSGLISTSIZE))
- PutMessages(M); /* show next page */
-
- Gotoxy(0,STARTLIST + old%MSGLISTSIZE); PutStr(" ");
- Gotoxy(0,STARTLIST + new%MSGLISTSIZE); PutStr("-> ");
- }
-
- void InitScreen(Mbox *Mailbox)
- { extern void PutMenus(void);
-
- Clrscr();
- PutHeader(Mailbox);
- PutMenus();
- PutMessages(Mailbox);
- SetCurMsg(Mailbox,Mailbox->CurMsg,0);
- }
-
- void SuspendMail(Mbox *Mailbox)
- { long omask;
-
- if (getenv("SHLVL") != NULL) /* there is a running (C) shell */
- { omask= sigsetmask(0);
- #ifdef __MINT__
- ttcooked(<old);
- #endif
- (void) kill(0, SIGTSTP);
- (void) sigsetmask(omask);
- #ifdef __MINT__
- ttraw(<old,<new);
- #endif
- InitScreen(Mailbox);
- }
- else
- PutStatus("No shell active");
- }
-
- void ListMessage(Mbox *M)
- { int cn;
- char ch,regel[MAXSTR+1];
- Msg *Current = M->Msglist[M->CurMsg];
- long start = Current->start;
- long end = M->Msglist[M->CurMsg+1]->start;
-
- Clrscr();
-
- OpenMailbox(M);
- fseek(M->fd,start,SEEK_SET);
- while (ftell(M->fd) < end)
- { for(cn=1;cn<LINES && ftell(M->fd) < end;cn++)
- { fgets (regel,MAXSTR,M->fd);
- fputs(regel,stdout);
- }
- PutStatus(" Press 'i' to return to menu ...");
- ch=GetChar();
- if(ch == 'i') break;
- Clrtoeol();
- }
- if(Current->flag == 'N')
- Current->flag = ' '; /* mark as read */
-
- CloseMailbox(M);
- InitScreen(M);
- }
-
- void SaveMessage(Mbox *M)
- { char msgname[MAXSTR+1],regel[MAXSTR+1];
- FILE *msg;
- long start = M->Msglist[M->CurMsg ]->start;
- long end = M->Msglist[M->CurMsg+1]->start;
-
- Gotoxy(0,STARTPROMPT + 1); Clrtoeol();
- PutStr("Save as: ");
- GetStr(msgname,MAXSTR);
- RemoveCR(msgname);
-
- if((msg = fopen (ux2dos(msgname), "w")) == NULL)
- { PutStatus("Can't save mail to file");
- return;
- }
- OpenMailbox(M);
- fseek(M->fd,start,SEEK_SET);
-
- while (ftell(M->fd) < end)
- { fgets(regel,MAXSTR,M->fd);
- fputs(regel,msg);
- }
-
- CloseMailbox(M);
- fclose(msg);
- PutStatus("Mail saved to: %s",msgname);
- }
-
- int StartEditor(Mbox *M,char *msgname)
- { char *arg[3];
- int stat=0;
-
- Clrscr();
- arg[0]=M->Editor; arg[1]=msgname; arg[2]=NULL;
-
- if(access(ux2dos(arg[0]),X_OK) == 0)
- {
- #ifdef __AMIGA__
- switch(vfork())
- #else
- switch((int)fork())
- #endif
- { case 0 : execv(arg[0],arg); break;
- case -1 : PutStatus("Can't fork editor !"); return -1;
- default : wait(&stat); break;
- }
- }
- else
- { PutStatus("Can't open editor %s",M->Editor);
- return -1;
- }
- return stat;
- }
-
- void DeadLetter(char *msgname)
- { char *dlname = DEADLETTER;
- PutStatus("Can't send message, saved in %s",dlname);
- remove(dlname);
- rename(msgname,dlname);
- }
-
- void OutboundMail(char *dest, char *subj, char *msgname)
- { /* this can be replaced by an external function that
- drops mail on Internet or uucp.
- */
- subj=subj; /* only to avoid compiler warnings ! */
- Gotoxy(0,LINES-3);
- PutStr("Only local mail: can't send to %s",dest);
- DeadLetter(msgname);
- }
-
- void MailMsgTo(Mbox *M,char *msgname,char *dest,char *subj)
- { char destbox[MAXSTR+1];
- char c=0,buffer[MAXSTR+1];
- time_t t;
- FILE *destfile, *msgfile;
-
- /* ask for confirmation or to reenter editor */
-
- while(c != 's')
- { Clrscr();
- Gotoxy(0,STARTPROMPT);
- PutStr("r)estart editor, s)end or f)orget ? ");
-
- switch(c=GetChar())
- { case 'f':
- PutStatus("Mail cancelled");
- InitScreen(M);
- remove(msgname); /* delete temporary file */
- return;
- case 'r':
- StartEditor(M,msgname);
- break;
- default:
- break;
- }
- }
-
- InitScreen(M);
-
- /* catch UUCP and internet mail */
-
- if(strchr(dest,'@') != NULL || strchr(dest,'!') != NULL)
- { OutboundMail(dest,subj,msgname);
- return;
- }
-
- sprintf (destbox, "%s/%s", MAILDIR, dest);
-
- if((destfile = fopen(ux2dos(destbox),"a")) == NULL)
- { DeadLetter(msgname);
- return;
- }
- time(&t);
-
- /* first line must be conform mail headers under UNIX */
-
- fprintf(destfile,"From %s %s",M->User,ctime(&t));
- fprintf(destfile,"To: %s\n",dest);
- fprintf(destfile,"Subject: %s\n",subj);
- fprintf(destfile,"Mailer: %s\n\n",version);
-
- if((msgfile = fopen(ux2dos(msgname),"r")) != NULL)
- { while (!feof(msgfile))
- { *buffer=0;
- fgets (buffer,MAXSTR,msgfile);
- fputs (buffer,destfile);
- }
- fclose(msgfile);
- remove(msgname); /* delete temporary file */
- }
- fprintf(destfile,"\n"); /* extra empty line */
- fclose(destfile);
- PutStatus("Mail sent !");
- }
-
- void SendMail(Mbox *M)
- { char *msgname=tmpnam(NULL);
- char dest[MAXSTR+1], subj[MAXSTR+1];
-
- Gotoxy(0,STARTPROMPT + 1); Clrtoeol();
- PutStr("Mail to: ");
- GetStr(dest,MAXSTR); RemoveCR(dest);
- Gotoxy(0,STARTPROMPT + 2); Clrtoeol();
- PutStr("Subject: ");
- GetStr(subj,MAXSTR); RemoveCR(subj);
-
- if(StartEditor(M,msgname))
- return;
- MailMsgTo(M,msgname,dest,subj);
- }
-
- void ForwardMail(Mbox *M)
- { char *msgname=tmpnam(NULL);
- char regel[MAXSTR+1], dest[MAXSTR+1], subj[MAXSTR+1];
- long start,end;
- FILE *msg;
-
- Gotoxy(0,STARTPROMPT + 1); Clrtoeol();
- PutStr("Forward to: ");
- GetStr(dest,MAXSTR); RemoveCR(dest);
- Gotoxy(0,STARTPROMPT + 2); Clrtoeol();
- sprintf(subj,"%s (fwd)",M->Msglist[M->CurMsg]->subject);
- PutStr("Subject: %s",subj);
- GetChar(); /* must be possible to edit later */
-
- if((msg = fopen (ux2dos(msgname), "w")) == NULL)
- { PutStatus("Can't open temporary file ");
- return;
- }
- OpenMailbox(M);
-
- start = M->Msglist[M->CurMsg ]->start;
- end = M->Msglist[M->CurMsg+1]->start;
- fseek(M->fd,start,SEEK_SET);
-
- while (ftell(M->fd) < end)
- { fgets(regel,MAXSTR,M->fd);
- fputs(PREFIX,msg);
- fputs(regel,msg);
- }
-
- CloseMailbox(M);
- fclose(msg);
-
- Gotoxy(40,STARTPROMPT + 2);
- PutStr("edit message ? (n) ");
- if(GetChar() == 'y')
- if(StartEditor(M,msgname))
- return;
-
- MailMsgTo(M,msgname,dest,subj);
- }
-
- void ReplyMail(Mbox *M)
- { char *msgname=tmpnam(NULL);
- char dest[MAXSTR+1], subj[MAXSTR+1];
-
- Gotoxy(0,STARTPROMPT + 1); Clrtoeol();
- PutStr("Reply to: %s",M->Msglist[M->CurMsg]->sender);
- strncpy(dest,M->Msglist[M->CurMsg]->sender,MAXSTR);
-
- Gotoxy(0,STARTPROMPT + 2); Clrtoeol();
- sprintf(subj,"Re: %s",M->Msglist[M->CurMsg]->subject);
- PutStr("Subject: %s",subj);
- GetChar(); /* must be possible to edit later */
-
- if(StartEditor(M,msgname))
- return;
- MailMsgTo(M,msgname,dest,subj);
- }
-
- void RebuildMailFile(Mbox *M)
- { FILE *new;
- char regel[MAXSTR+1],newname[MAXSTR+1];
- char *statusline = "Status: RO\n";
- long start,end;
- int x,delflag=0;
-
- /* check if we need to update */
-
- for(x=0;x<M->Count;x++)
- if(M->Msglist[x]->flag == 'D')
- break;
- if(x < M->Count)
- { Gotoxy(40,STARTPROMPT); Clrtoeol();
- PutStr("Delete marked messages ? (n) ");
- if(GetChar() == 'y')
- delflag = 1;
- }
-
- PutStatus("Updating mailbox %s ....",M->Path);
- sprintf(newname,"%s.new",M->Path);
- if((new = fopen (ux2dos(newname), "w")) == NULL)
- { PutStatus("Can't open new mailbox");
- return;
- }
- OpenMailbox(M);
-
- for(x=0;x<M->Count;x++)
- { if(M->Msglist[x]->flag == 'D' && delflag == 1)
- continue; /* skip deleted messages */
-
- start = M->Msglist[x ]->start;
- end = M->Msglist[x+1]->start;
- fseek(M->fd,start,SEEK_SET);
-
- if(fgets(regel,MAXSTR,M->fd) != NULL)
- fputs(regel,new); /* Write first (From) line */
-
- while (ftell(M->fd) < end && !feof(M->fd))
- { fgets(regel,MAXSTR,M->fd);
-
- if(M->Msglist[x]->flag != 'N')
- {
- /* Add a new statusline */
- if(M->Msglist[x]->status == 0)
- { while(strchr(regel,':') != NULL &&
- ftell(M->fd) < end && !feof(M->fd))
- { fputs(regel,new);
- fgets(regel,MAXSTR,M->fd);
- }
- fputs(statusline,new);
- M->Msglist[x]->status = 1;
- }
-
- /* Or update an existing statusline */
- if(!strncmp(regel,"Status:",7))
- { fputs(statusline,new);
- continue;
- }
- }
- fputs(regel,new);
- }
- }
-
- /* this is to copy new messages arrived during the session !! */
-
- /* goto 'official' end of file */
- fseek(M->fd,M->Msglist[M->Count]->start,SEEK_SET);
-
- while (fgets(regel,MAXSTR,M->fd) != NULL)
- fputs(regel,new);
-
- CloseMailbox(M);
- fclose(new);
- if(! remove(M->Path))
- if( !rename(newname,M->Path))
- return;
- PutStatus("Update mailbox %s failed",M->Path);
- }
-
- void HandleQuit(Mbox *M)
- { Gotoxy(40,STARTPROMPT);
- PutStr("Do you want to quit ? (y) ");
- if(GetChar() != 'n')
- { RebuildMailFile(M);
- putchar('\n');
- EndTermcap();
- #ifdef __MINT__
- ttcooked(<old);
- #endif
- exit(0);
- }
- }
-
- void HandleExit(void)
- { Gotoxy(40,STARTPROMPT);
- PutStr("Exit without update ? (y) ");
- if(GetChar() != 'n')
- { putchar('\n');
- EndTermcap();
- #ifdef __MINT__
- ttcooked(<old);
- #endif
- exit(0);
- }
- }
-
- int main(int argc,char *argv[])
- { char cmd[MAXSTR+1];
- char editflag=0,fileflag=0;
- Mbox Mailbox;
- char *tmp;
-
- #ifndef __MINT__
- struct termios p;
-
- tcgetattr(fileno(stdin),&p);
- p.c_lflag &= ~ICANON;
- p.c_cc[VTIME] = 0;
- p.c_cc[VMIN] = 1;
- tcsetattr(fileno(stdin),TCSANOW,&p);
- #else
- ttraw(<old,<new); /* disable Ctrl-Z */
- #endif
-
- while(--argc>0) /* parse options */
- {
- if(*argv[1]=='-')
- { switch(*(++argv[1]))
- { case 'f':
- strcpy(Mailbox.Path,argv[2]);
- fileflag = 1;
- break;
- case 'e':
- strcpy(Mailbox.Editor,argv[2]);
- editflag = 1;
- break;
- default :
- usage();
- }
- }
- ++argv;
- }
- InitTermcap();
-
- /* Initialize */
-
- if((tmp=getenv("LOGNAME")) == NULL)
- tmp="root";
- strncpy(Mailbox.User,tmp,MAXNAME);
-
- if(!fileflag)
- sprintf (Mailbox.Path, "%s/%s", MAILDIR, Mailbox.User);
- if(!editflag)
- sprintf (Mailbox.Editor, "%s", EDITOR);
-
- BuildMailList(&Mailbox);
- InitScreen(&Mailbox);
-
- while(1)
- { Gotoxy(0,STARTPROMPT); Clrtoeol();
- PutStr("Command: ");
- *cmd=GetChar();
- if(!isdigit(*cmd))
- PutStatus(""); /* clear statusline */
- switch(*cmd)
- { case'\r':
- case'\n': ListMessage(&Mailbox);
- SetCurMsg(&Mailbox,Mailbox.CurMsg+1,0);
- break;
- case '!': SuspendMail(&Mailbox); /* shell */
- break;
- case 'd': Mailbox.Msglist[Mailbox.CurMsg]->flag = 'D';
- PutMessage(&Mailbox,Mailbox.CurMsg);
- SetCurMsg(&Mailbox,Mailbox.CurMsg+1,0);
- break;
- case 'u': Mailbox.Msglist[Mailbox.CurMsg]->flag = 'U';
- PutMessage(&Mailbox,Mailbox.CurMsg);
- SetCurMsg(&Mailbox,Mailbox.CurMsg,0);
- break;
- case 'm': SendMail(&Mailbox);
- break;
- case 'f': ForwardMail(&Mailbox);
- break;
- case 'r': ReplyMail(&Mailbox);
- break;
- case 'k': SetCurMsg(&Mailbox,Mailbox.CurMsg-1,1);
- break;
- case 'j': SetCurMsg(&Mailbox,Mailbox.CurMsg+1,1);
- break;
- case 's': SaveMessage(&Mailbox);
- break;
- case '$': RebuildMailFile(&Mailbox);
- BuildMailList(&Mailbox);
- InitScreen(&Mailbox);
- break;
- case 'q': HandleQuit(&Mailbox);
- break;
- case 'x': HandleExit();
- break;
- default : if(atoi(cmd) != 0)
- { GetStr(cmd+1,MAXSTR-1);
- SetCurMsg(&Mailbox,atoi(cmd) - 1,1);
- PutStatus("Current message set to %d",
- Mailbox.CurMsg + 1);
- }
- else
- PutStatus("Unknown command !");
- }
- }
- }
-